import { ImageData } from '@/types/image'
import { Dataset } from '@/types/dataset'
import { Task } from '@/types/task'

/**
 * Validates image data structure
 */
export function validateImageData(data: ImageData): void {
    if (!data || typeof data !== 'object') {
        throw new Error('Invalid image data: data must be an object')
    }

    // Check required fields
    if (!data.id) {
        throw new Error('Invalid image data: missing id')
    }

    if (!data.type) {
        throw new Error('Invalid image data: missing type')
    }

    if (!['2D', '3D'].includes(data.type)) {
        throw new Error('Invalid image data: type must be 2D or 3D')
    }

    if (!data.format) {
        throw new Error('Invalid image data: missing format')
    }

    if (!['DICOM', 'NIfTI', 'PNG', 'JPEG'].includes(data.format)) {
        throw new Error('Invalid image data: format must be DICOM, NIfTI, PNG, or JPEG')
    }

    // Check dimensions
    if (!data.dimensions || typeof data.dimensions !== 'object') {
        throw new Error('Invalid image data: missing dimensions')
    }

    if (typeof data.dimensions.width !== 'number' || data.dimensions.width <= 0) {
        throw new Error('Invalid image data: dimensions must be positive numbers')
    }

    if (typeof data.dimensions.height !== 'number' || data.dimensions.height <= 0) {
        throw new Error('Invalid image data: dimensions must be positive numbers')
    }

    // Check depth for 3D images
    if (data.type === '3D') {
        if (typeof data.dimensions.depth !== 'number' || data.dimensions.depth <= 0) {
            throw new Error('Invalid image data: 3D images must have depth dimension')
        }
    }

    // Check pixel spacing
    if (!Array.isArray(data.pixelSpacing)) {
        throw new Error('Invalid image data: pixelSpacing must be an array')
    }

    if (data.pixelSpacing.some(spacing => typeof spacing !== 'number' || spacing <= 0)) {
        throw new Error('Invalid image data: pixelSpacing must be positive numbers')
    }

    // Check window values
    if (typeof data.windowCenter !== 'number') {
        throw new Error('Invalid image data: windowCenter must be a number')
    }

    if (typeof data.windowWidth !== 'number' || data.windowWidth <= 0) {
        throw new Error('Invalid image data: windowWidth must be positive')
    }

    // Check pixel data
    if (!(data.pixelData instanceof ArrayBuffer)) {
        throw new Error('Invalid image data: pixelData must be ArrayBuffer')
    }
}

/**
 * Validates dataset structure
 */
export function validateDataset(data: Dataset): void {
    if (!data || typeof data !== 'object') {
        throw new Error('Invalid dataset: data must be an object')
    }

    // Check required fields
    if (!data.id) {
        throw new Error('Invalid dataset: missing id')
    }

    if (!data.name) {
        throw new Error('Invalid dataset: missing name')
    }

    if (!data.description) {
        throw new Error('Invalid dataset: missing description')
    }

    if (!data.type) {
        throw new Error('Invalid dataset: missing type')
    }

    if (!['2D', '3D'].includes(data.type)) {
        throw new Error('Invalid dataset: type must be 2D or 3D')
    }

    // Check arrays
    if (!Array.isArray(data.tasks)) {
        throw new Error('Invalid dataset: tasks must be an array')
    }

    if (!Array.isArray(data.images)) {
        throw new Error('Invalid dataset: images must be an array')
    }

    // Check dates
    if (!(data.createdAt instanceof Date)) {
        throw new Error('Invalid dataset: createdAt must be a Date')
    }

    if (!(data.updatedAt instanceof Date)) {
        throw new Error('Invalid dataset: updatedAt must be a Date')
    }
}

/**
 * Validates task structure
 */
export function validateTask(data: Task): void {
    if (!data || typeof data !== 'object') {
        throw new Error('Invalid task: data must be an object')
    }

    // Check required fields
    if (!data.id) {
        throw new Error('Invalid task: missing id')
    }

    if (!data.name) {
        throw new Error('Invalid task: missing name')
    }

    if (!data.type) {
        throw new Error('Invalid task: missing type')
    }

    if (!['detection', 'classification', 'segmentation'].includes(data.type)) {
        throw new Error('Invalid task: type must be detection, classification, or segmentation')
    }

    if (!data.description) {
        throw new Error('Invalid task: missing description')
    }

    if (!data.status) {
        throw new Error('Invalid task: missing status')
    }

    if (!['idle', 'running', 'completed', 'error'].includes(data.status)) {
        throw new Error('Invalid task: status must be idle, running, completed, or error')
    }

    // Check config
    if (!data.config || typeof data.config !== 'object') {
        throw new Error('Invalid task: config must be an object')
    }

    if (!data.config.parameters || typeof data.config.parameters !== 'object') {
        throw new Error('Invalid task: config must have parameters')
    }
}

/**
 * Formats API response with consistent structure
 */
export function formatApiResponse<T>(
    data: T,
    success: boolean,
    error?: Error | string
): {
    success: boolean
    data: T
    error: any
    timestamp: Date
} {
    let formattedError = null

    if (!success) {
        if (error instanceof Error) {
            formattedError = {
                message: error.message,
                name: error.name,
                ...(error as any).code && { code: (error as any).code }
            }
        } else if (typeof error === 'string') {
            formattedError = {
                message: error
            }
        } else {
            formattedError = {
                message: 'Unknown error'
            }
        }
    }

    return {
        success,
        data,
        error: formattedError,
        timestamp: new Date()
    }
}